﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Main.PrimitivesCommunication;
using Newtonsoft.Json;

namespace Main.Packets
{
    public enum PacketTypes
    {
        ConnectionRequestPacket,
        ConnectionConfirmationPacket,
        FreeConnectionPacket,
        DataPacket,
        PositiveAcknowledgmentPacket,
        NegativeAcknowledgmentPacket,
        None
    }

    public class PacketType
    {
        private int bits8To6;
        private int bit5;
        private int bits4To2;
        private int bit1;

        public PacketType()
        {
        }

        public PacketType(int bits8To6, int bit5, int bits4To2, int bit1)
        {
            this.bits8To6 = bits8To6;
            this.bit5 = bit5;
            this.bits4To2 = bits4To2;
            this.bit1 = bit1;
        }

        #region Propriétés
        public string Bits8To6
        {
            get
            {
                return Convert.ToString(bits8To6, 2).PadLeft(3, '0');
            }
            set
            {
                bits8To6 = Convert.ToInt32(value, 2);
            }
        }
        public string Bit5
        {
            get
            {
                return Convert.ToString(bit5, 2);
            }
            set
            {
                bit5 = Convert.ToInt32(value, 2);
            }
        }
        public string Bits4To2
        {
            get
            {
                return Convert.ToString(bits4To2, 2).PadLeft(3, '0');
            }
            set
            {
                bits4To2 = Convert.ToInt32(value, 2);
            }
        }
        public string Bit1
        {
            get
            {
                return Convert.ToString(bit1, 2);
            }
            set
            {
                bit1 = Convert.ToInt32(value, 2);
            }
        }

        [JsonIgnore]
        public PacketTypes Type
        {
            get
            {
                if (bit1 == 0)
                {
                    return PacketTypes.DataPacket;
                }
                else if (bit5 == 1)
                {
                    return PacketTypes.FreeConnectionPacket;
                }
                else if (bits4To2 == 5)
                {
                    return PacketTypes.ConnectionRequestPacket;
                }
                else if (bits4To2 == 7)
                {
                    return PacketTypes.ConnectionConfirmationPacket;
                }
                else if (bits4To2 == 0)
                {
                    return PacketTypes.PositiveAcknowledgmentPacket;
                }
                else if (bits4To2 == 4)
                {
                    return PacketTypes.NegativeAcknowledgmentPacket;
                }
                else
                    throw new NotImplementedException();
            }
        }

        #endregion

        public static PacketType CreateTypeForPacket(string arrayOfBits)
        {
            PacketType type = new PacketType();
            type.bits8To6 = Convert.ToInt32(arrayOfBits.Substring(0, 3), 2);
            type.bit5 = Convert.ToInt32(arrayOfBits.Substring(3, 1), 2);
            type.bits4To2 = Convert.ToInt32(arrayOfBits.Substring(4, 3), 2);
            type.bit1 = Convert.ToInt32(arrayOfBits.Substring(7, 1), 2);
            return type;
        }

        public static PacketType CreateTypeForConnectionRequestPacket()
        {
            return new PacketType(0,0,5,1);
        }

        public static PacketType CreateTypeForConnectionConfirmationPacket()
        {
            return new PacketType(0, 0, 7, 1);
        }

        public static PacketType CreateTypeForFreeConnectionPacket()
        {
            return new PacketType(0, 1, 1, 1);
        }

        public static PacketType CreateTypeForDataPacket(int pr, bool hasNext, int ps)
        {
            return new PacketType(pr, (hasNext ? 1 : 0), ps, 0);
        }

        public static PacketType CreateTypeForPositiveAcknowledgmentPacket(int pr)
        {
            return new PacketType(pr, 0, 0, 1);
        }

        public static PacketType CreateTypeForNegativeAcknowledgmentPacket(int pr)
        {
            return new PacketType(pr, 0, 4, 1);
        }
    }
}
